package com.qidian.by.search.repository;

import com.qidian.by.search.dto.SearchItem;
import com.qidian.by.search.service.SearchItemService;
import com.qidian.by.util.pojo.EsResult;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.engine.Engine;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;

import javax.naming.directory.SearchResult;
import java.io.IOException;
import java.util.*;

/**
 * @Author: CoolPro
 * @Description:
 * @Time: 2024-05-16 14:41
 **/
@Repository
public abstract class SearchItemRepository implements SearchItemService {
    @Value("${INDEX_NAME}")
    private String indexName;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public int saveSearchItem(SearchItem searchItem) {
        IndexRequest indexRequest = new IndexRequest(indexName);
        Map<String, String> data = new HashMap<>();
        data.put("itemId", searchItem.getItemId().toString());
        data.put("itemTitle", searchItem.getItemTitle());
        data.put("itemPrice", searchItem.getItemPrice().toString());
        data.put("image", searchItem.getImageUrl().size()>0 ? searchItem.getImageUrl().get(0) : "https://img1.baidu.com/it/u=415449740,540746270&fm=253&fmt=auto&app=138&f=GIF?w=500&h=500");
        data.put("acclaim", searchItem.getAcclaim() != null ? searchItem.getAcclaim().toString() : "0");
        data.put("buyCount", searchItem.getBuyCount() != null ? searchItem.getBuyCount().toString() : "0");
        indexRequest.source(data);
        try {
            IndexResponse response = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
            if (response.getResult().getLowercase().equalsIgnoreCase("CREATED")) {
                return 1;
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return 0;
    }

    @Override
    public List<SearchItem> listSearchItem(String kw, int page, int limit) {
        SearchRequest request = new SearchRequest(indexName);
        SearchSourceBuilder  builder = new SearchSourceBuilder();
        if (kw != null && !kw.equals(""))
            builder.query(QueryBuilders.matchQuery("itemTitle", kw));
        builder.from((page - 1) * limit);
        builder.size(limit);
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("itemTitle");
        highlightBuilder.preTags("<font color='red'>");
        highlightBuilder.postTags("</font>");
        builder.highlighter(highlightBuilder);
        request.source(builder);
//            查询
        try {
            SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
            Iterator<SearchHit> iterator = response.getHits().iterator();
            List<SearchItem> items = new ArrayList<>();
            while (iterator.hasNext()) {
                SearchHit data = iterator.next();
                Map<String, Object> sourceMap = data.getSourceAsMap();
                SearchItem goodsItem = EsResult.json2object(EsResult.object2json(sourceMap), SearchItem.class);
//                    获取高亮显示的部分
                Map<String, HighlightField> highlightFields = data.getHighlightFields();
                HighlightField itemTitle = highlightFields.get("itemTitle");
                if (itemTitle != null) {
                    Text[] fragments = itemTitle.getFragments();
                    if (fragments != null && fragments.length > 0) {
                        goodsItem.setItemTitle(fragments[0].string());
                    }
                }
                items.add(goodsItem);
            }
            return items;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public Integer selectCount(String kw) {
        SearchRequest request = new SearchRequest(indexName);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        if (Objects.nonNull(kw)) {
            builder.query(QueryBuilders.matchQuery("itemTitle", kw).fuzziness(Fuzziness.ONE));
            request.source(builder);
            try {
                SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
                return (int) response.getHits().getTotalHits().value;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }

    @Override
    public abstract EsResult query(int page, int limit, String kw);
}
